package com.sunlee.admin.api.module.job.template.impl;

import com.aspose.slides.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sunlee.admin.api.constant.StringConstant;
import com.sunlee.admin.api.module.job.template.GeneratePptTemplate;
import com.sunlee.admin.api.module.job.template.context.GeneratePptContext;
import com.sunlee.common.core.exception.BusinessException;
import com.sunlee.common.service.entity.ThirdCategoryEntity;
import com.sunlee.common.service.entity.ThirdProductCategoryMappingEntity;
import com.sunlee.common.service.entity.ThirdProductEntity;
import com.sunlee.common.service.service.ThirdCategoryService;
import com.sunlee.common.service.service.ThirdProductCategoryMappingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author sunlee
 * @date 2023-03-04
 */
@Slf4j
@Service
public class GeneratePptFirstPpt extends GeneratePptTemplate {
    private static final List<String> NON_REPLACE_STRING_LIST;
    private static final List<String> REPLACE_STRING_LIST;

    static {
        NON_REPLACE_STRING_LIST = new ArrayList<>();
        NON_REPLACE_STRING_LIST.add("第一部");
        NON_REPLACE_STRING_LIST.add("第一部分");
        NON_REPLACE_STRING_LIST.add("第一章");
        NON_REPLACE_STRING_LIST.add("第一节");
        NON_REPLACE_STRING_LIST.add("第一张");
        NON_REPLACE_STRING_LIST.add("第一种");
        NON_REPLACE_STRING_LIST.add("第一章节");
        NON_REPLACE_STRING_LIST.add("第一课");
        NON_REPLACE_STRING_LIST.add("第一个");
        NON_REPLACE_STRING_LIST.add("第一组");
        NON_REPLACE_STRING_LIST.add("第一季度");
        NON_REPLACE_STRING_LIST.add("第一年");

        REPLACE_STRING_LIST = new ArrayList<>();
        REPLACE_STRING_LIST.add("第一PPT");
        REPLACE_STRING_LIST.add("第一 PPT");
        REPLACE_STRING_LIST.add("第一ppt");
        REPLACE_STRING_LIST.add("第一 ppt");
        REPLACE_STRING_LIST.add("1ppt");
        REPLACE_STRING_LIST.add("1 ppt");
        REPLACE_STRING_LIST.add("1PPT");
        REPLACE_STRING_LIST.add("1 PPT");
    }


    @Autowired
    private ThirdProductCategoryMappingService thirdProductCategoryMappingService;

    @Autowired
    private ThirdCategoryService thirdCategoryService;

    @Override
    protected void removeSlide(GeneratePptContext context) {
        ISlideCollection slides = context.getPresentation().getSlides();
        // 处理倒数第二张的包图网幻灯片（ibaotu.com）
        int indexLast2 = slides.size() - 2;
        removeSlide(slides, indexLast2, "ibaotu.com");
        // 处理最后一张幻灯片（www.1ppt.com ）
        int indexLast = slides.size() - 1;
        removeSlide(slides, indexLast, "www.1ppt.com");
    }

    @Override
    protected void handleText(GeneratePptContext context) {
        for (ISlide slide : context.getPresentation().getSlides()) {
            ITextFrame[] textFramesSlideLast2 = SlideUtil.getAllTextBoxes(slide);
            for (ITextFrame iTextFrame : textFramesSlideLast2) {
                for (IParagraph para : iTextFrame.getParagraphs()) {
                    for (IPortion port : para.getPortions()) {
                        String text = port.getText();

                        for (String textKey : REPLACE_STRING_LIST) {
                            if (text.contains(textKey)) {
                                text = text.replace(textKey, StringConstant.APP_NAME_PPT);
                                break;
                            }
                        }

                        if (text.contains("第一")) {
                            if (NON_REPLACE_STRING_LIST.stream().noneMatch(text::contains)) {
                                text = text.replace("第一", StringConstant.APP_NAME);
                            }
                        }
                        port.setText(text);
                    }
                }
            }
        }
    }

    /**
     * 移除幻灯片
     *
     * @param slides  幻灯片集合
     * @param index   需移除的集合下标
     * @param keyword 移除条件
     */
    private void removeSlide(ISlideCollection slides, int index, String keyword) {
        ISlide itemLast2 = slides.get_Item(index);
        ITextFrame[] textFramesSlideLast2 = SlideUtil.getAllTextBoxes(itemLast2);
        try {
            for (ITextFrame iTextFrame : textFramesSlideLast2) {
                for (IParagraph para : iTextFrame.getParagraphs()) {
                    for (IPortion port : para.getPortions()) {
                        if (port.getText().contains(keyword)) {
                            slides.remove(itemLast2);
                            throw new BusinessException("已经移除：" + index);
                        }
                    }
                }
            }
        } catch (BusinessException e) {
        }
    }

    @Override
    protected boolean isHandleSlide(GeneratePptContext context) {
        //校验PPT类型是否为素材或图表
        ThirdProductEntity curThirdProductEntity = context.getCurThirdProductEntity();

        // 查询商品与分类映射关系
        List<ThirdProductCategoryMappingEntity> thirdProductCategoryMappingList = thirdProductCategoryMappingService.list(new LambdaQueryWrapper<ThirdProductCategoryMappingEntity>()
                .eq(ThirdProductCategoryMappingEntity::getProductId, curThirdProductEntity.getId()));

        // 查询商品分类
        List<ThirdCategoryEntity> categoryList = thirdCategoryService.list(new LambdaQueryWrapper<ThirdCategoryEntity>()
                .in(ThirdCategoryEntity::getId, thirdProductCategoryMappingList.stream().map(ThirdProductCategoryMappingEntity::getCategoryId).collect(Collectors.toList())));

        for (ThirdCategoryEntity thirdCategoryEntity : categoryList) {
            String name = thirdCategoryEntity.getCategoryId();
            if (name.startsWith("sucai/") || name.startsWith("tubiao/")) {
                return true;
            }
        }

        return false;
    }

    /**
     * 对素材类型和图表类型的PPT进行母版版式替换
     *
     * @param context 上下文
     */
    @Override
    protected void handleSlide(GeneratePptContext context) {

        IMasterSlideCollection masters = context.getPresentation().getMasters();
        ISlideCollection slides = context.getPresentation().getSlides();
        // 母版插入首个位置
        masters.insertClone(0, context.getMasterSlide());

        IMasterSlide firstMasterSlide = masters.get_Item(0);

        // 获取可用版式
        HashMap<String, ILayoutSlide> baseLayoutMap = convertMasterLayoutSlide(firstMasterSlide);

        // 使用过的子版式
        Set<ILayoutSlide> useLayout = new LinkedHashSet<>();
        // 是否使用带头部的子版式
        boolean isTitle = true;
        for (ISlide slide : slides) {
            String childrenName = convertLayoutName(slide.getLayoutSlide().getName(), isTitle);

            ILayoutSlide newLayoutSlide = baseLayoutMap.get(childrenName);
            slide.setLayoutSlide(newLayoutSlide);

            useLayout.add(newLayoutSlide);

            if (isTitle) {
                isTitle = false;
            }
        }
        // 移除没有被使用的母版
        masters.removeUnused(true);

        // 移除没有被使用的子版式
        Set<ILayoutSlide> deleteLayout = new LinkedHashSet<>();
        for (ILayoutSlide layout : firstMasterSlide.getLayoutSlides()) {
            if (useLayout.contains(layout)) {
                continue;
            }
            deleteLayout.add(layout);
        }
        deleteLayout.forEach(ILayoutSlide::remove);

    }

    /**
     * 第一PPT母版规则：
     * 标题幻灯片  对应 白色背景
     * 1_标题和内容  对应 蓝色背景
     * 标题和内容  对应 黑色背景
     * 2_标题和内容  对应 红色背景
     *
     * @return 根据第三方母版版式名（key），返回本地对应的母版版式（value）
     */
    private HashMap<String, ILayoutSlide> convertMasterLayoutSlide(IMasterSlide firstMasterSlide) {

        // 重新获取首个母版下所有幻灯片版式
        IMasterLayoutSlideCollection baseLayoutSlides = firstMasterSlide.getLayoutSlides();

        // 自定义版式名称转换
        HashMap<String, ILayoutSlide> baseLayoutMap = new HashMap<>(16);
        for (ILayoutSlide base : baseLayoutSlides) {
            baseLayoutMap.put(base.getName(), base);
        }
        return baseLayoutMap;
    }

    private String convertLayoutName(String name, boolean isTitle) {
        String type = "白";
        if ("标题幻灯片".equals(name) || "2_自定义版式".equals(name)) {
            type = "白";
        }
        if ("1_自定义版式".equals(name) || "1_标题和内容".equals(name)) {
            type = "蓝";
        }
        if ("标题和内容".equals(name) || "自定义版式".equals(name)) {
            type = "黑";
        }
        if ("2_标题和内容".equals(name)) {
            type = "红";
        }

        if (isTitle) {
            type += "-title";
        }
        return type;
    }
}
